import { TouchableOpacity, View, Text, StyleSheet } from "react-native";
import type { ViewStyle, StyleProp, TextProps, TextStyle } from "react-native";

// TODO 缺少类型可以参考官网: https://github.com/react-native-dialogs/react-native-dialogs
// @ts-ignore
import DialogAndroid from "react-native-dialogs";

// 设定全局默认值, 这样就不用每次都设置
const defaultOpt = {
  positiveText: "确定", // 确定按钮文本
  neutralText: "取消", // 清空按钮文本
  contentColor: "rgba(0, 0, 0, 0.8)", // 内容颜色
  widgetColor: "#5e5e5e" // 选中的颜色
};
DialogAndroid.assignDefaults(defaultOpt);

export type Item = {
  [k: string]: any;
  label?: string;
  value?: string;
};

export type Props = {
  /** 操作类型 */
  type: "select" | "multiple";

  /** 选择器数据 */
  items: Item[];

  /** 选择value后的颜色 */
  valueColor?: string;

  /** 错误提示文本 */
  errorTip?: string;

  /** 选中的值(对应类型 select) */
  selectedId?: string;

  /** 选中的值(对应类型 multiple) */
  selectedIds?: string[];

  /** 多选时多个 label 的分割符, 默认为: , */
  splitSymbol?: string;

  /** 标题 */
  title?: string;

  /** 容器样式 */
  containerStyles?: StyleProp<ViewStyle>;

  /** 内容容器样式 */
  contentContainerStyles?: StyleProp<ViewStyle>;

  /** 内容 Text props  */
  TextProps?: TextProps;

  /** 内容 Text 样式 */
  TextStyles?: StyleProp<TextStyle>;

  /** 右边下拉三角的颜色 */
  rightComponentColor?: string;

  /** label Key  */
  labelKey?: string;

  /** value key */
  valueKey?: string;

  /** 空数据文本 */
  emptyText?: string;

  /** 占位文本 */
  placeholder?: string;

  /** 是否禁用 */
  disabled?: boolean;

  /** 自定义点击回调 */
  onPress?: () => void;

  /** 选择回调 */
  selectedValue: (item?: Item | Item[]) => void;

  /** 渲染内容回调, 接收 ComtentComp 为空内容组件 */
  render?: (
    ComtentCompFn: (cm: React.ReactNode) => React.ReactNode,
    selectItems: Item | Item[],
    open: () => void
  ) => React.ReactNode;

  /** 右边图标 */
  rightComponent?: () => React.ReactNode;

  /** 空数据组件 */
  emptyComponent?: () => React.ReactNode;

  /** react-native-dialogs 配置 */
  dialogOption?: any; // TODO 类型
};

const DialogRow = (props: Props) => {
  const labelKey = () => props.labelKey || "label";
  const valueKey = () => props.valueKey || "value";

  const onPress = async () => {
    if (props.items.length === 0 || props.disabled) return;

    if (props.type === "select") {
      const opt = props.dialogOption || {};
      const res = await DialogAndroid.showPicker(props.title, null, {
        items: props.items,
        selectedId: props.selectedId,
        neutralText: opt.type ? defaultOpt.neutralText : "",
        // 对应的 key 不能指定默认值
        idKey: valueKey(),
        labelKey: labelKey(),
        ...opt
      });
      if (res.selectedItem) {
        props.selectedValue && props.selectedValue(res.selectedItem);
      } else {
        props.selectedValue && props.selectedValue();
      }
    } else if (props.type === "multiple") {
      const res = await DialogAndroid.showPicker(props.title, null, {
        type: DialogAndroid.listCheckbox,
        neutralIsClear: true,
        selectedIds: props.selectedIds,
        items: props.items,
        idKey: valueKey(),
        labelKey: labelKey(),
        ...(props.dialogOption || {})
      });
      if (res.selectedItems) {
        props.selectedValue && props.selectedValue(res.selectedItems);
      } else {
        props.selectedValue && props.selectedValue();
      }
    }
  };
  const EmptyComp = props.emptyComponent ? props.emptyComponent() : <Text>{props.emptyText || "暂无数据"}</Text>;
  const PlayComp = (
    <Text style={[styles.text, { color: "#767676", fontWeight: "normal" }, props.TextStyles]}>
      {props.placeholder ? props.placeholder : "请选择"}
    </Text>
  );
  const ComtentComp = (child: React.ReactNode = PlayComp) => {
    return props.items.length ? (
      <View
        style={[
          styles.labelContainer,
          {
            borderColor: props.errorTip ? "#f56c6c" : "#ccc",
            opacity: props.disabled ? 0.7 : 1,
            backgroundColor: props.disabled ? "#eaeaea" : "#fff"
          },
          props.contentContainerStyles
        ]}
      >
        {child}
        {props.rightComponent ? (
          props.rightComponent()
        ) : (
          <View
            style={[
              styles.triangle,
              { borderTopColor: props.rightComponentColor ? props.rightComponentColor : "#6e6e6e" }
            ]}
          />
        )}
      </View>
    ) : (
      EmptyComp
    );
  };

  // 获取当前选中的 item
  const getSelectItems = () => {
    let ret: any[] = [];
    if (props.selectedId) {
      const target = props.items.find(e => e[valueKey()] === props.selectedId);
      if (target) ret = [target];
    } else if (props.selectedIds?.length) {
      ret = props.selectedIds.reduce((pre: Item[], cur) => {
        const target = props.items.find(e => e[valueKey()] === cur);
        if (target) {
          return [...pre, target];
        } else {
          return pre;
        }
      }, []);
    }
    return ret;
  };

  let Content: React.ReactNode = <Text></Text>;
  if (props.render) {
    // 自定义渲染
    Content = props.render(ComtentComp, getSelectItems(), onPress);
  } else {
    const text = getSelectItems()
      .map(e => e[labelKey()])
      .join(props.splitSymbol || ",");

    Content = ComtentComp(
      text ? (
        <Text
          numberOfLines={1}
          ellipsizeMode="tail"
          {...props.TextProps}
          style={[styles.text, { color: props.valueColor || defaultOpt.widgetColor }, props.TextStyles]}
        >
          {text}
        </Text>
      ) : (
        PlayComp
      )
    );
  }

  /** 错误提示 */
  const ErrTipComp = props.errorTip && (
    <View style={styles.errTipContainer}>
      <Text style={styles.errTip}>{props.errorTip}</Text>
    </View>
  );

  return (
    <TouchableOpacity
      style={[styles.container, props.containerStyles]}
      activeOpacity={props.disabled ? 1 : 0.2}
      onPress={onPress}
    >
      {Content}
      {ErrTipComp}
    </TouchableOpacity>
  );
};

export const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingRight: 20,
    paddingLeft: 20,
    justifyContent: "center",
  },
  labelContainer: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    gap: 4,
    padding: 4,
    paddingLeft: 8,
    paddingRight: 8,
    borderStyle: "solid",
    borderWidth: 1,
    borderRadius: 4
  },
  errTipContainer: {
    marginLeft: 4
  },
  errTip: {
    fontSize: 10,
    color: "#f56c6c"
  },
  // 下三角形
  triangle: {
    width: 12,
    borderColor: "rgba(0,0,0,0)",
    borderWidth: 6,
    borderStyle: "solid",
    transform: [{ translateY: 5 }]
  },
  text: {
    width: "90%",
    fontSize: 14,
    fontWeight: "bold"
  }
});

export default DialogRow;
